(function(){

    //***********************  START HELPERS  *************************//

    //returns border width for some element
    function __getBorderWidth(element) {
        var res = new Object();
        res.left = 0; res.top = 0; res.right = 0; res.bottom = 0;

         var elStyle = window.getComputedStyle(element, null);
         res.left = parseInt(elStyle.borderLeftWidth.slice(0, -2));
         res.top = parseInt(elStyle.borderTopWidth.slice(0, -2));
         res.right = parseInt(elStyle.borderRightWidth.slice(0, -2));
         res.bottom = parseInt(elStyle.borderBottomWidth.slice(0, -2));

        return res;
    }


    //returns the absolute position of some element within document
    //from http://blogs.korzh.com/progtips/2008/05/28/absolute-coordinates-of-dom-element-within-document.html
    function getElementAbsolutePos(elemID) {
        var element;
        if (typeof(elemID) == "string")	{
            element = document.getElementById(elemID);
        }
        else {
            element = elemID;
        }

        var res = new Object();
        res.x = 0; res.y = 0;
        if (element !== null) {
            res.x = element.offsetLeft;

            var offsetParent = element.offsetParent;
            var offsetParentTagName = offsetParent != null ? offsetParent.tagName.toLowerCase() : "";

            res.y = element.offsetTop;

            var parentNode = element.parentNode;
            var borderWidth = null;

            while (offsetParent != null) {
                res.x += offsetParent.offsetLeft;
                res.y += offsetParent.offsetTop;

                var parentTagName = offsetParent.tagName.toLowerCase();

                if (parentTagName == "td") {
                    borderWidth = __getBorderWidth(offsetParent);
                    res.x += borderWidth.left;
                    res.y += borderWidth.top;
                }

                if (offsetParent != document.body && offsetParent != document.documentElement) {
                    res.x -= offsetParent.scrollLeft;
                    res.y -= offsetParent.scrollTop;
                }


                    while (offsetParent != parentNode && parentNode !== null) {
                        res.x -= parentNode.scrollLeft;
                        res.y -= parentNode.scrollTop;
                        parentNode = parentNode.parentNode;
                    }

                parentNode = offsetParent.parentNode;
                offsetParent = offsetParent.offsetParent;
            }
        }
        return res;
    }

    //***********************  END HELPERS  *************************//

    //statics
    var BASIC_URL = "http://localhost:8080/KiWi2/";
    var IN_SELECTION = ["div","p","h1","h2","h3","h4","img","form","ul","li","td","tr","table"];

    //global vars
    var outer_container = undefined;
    var inner_container = undefined;
    var selector_box = undefined;
    var marked_boxes = undefined;

    var unload = function() {
        //unshift html
        var html = document.getElementsByTagName("html")[0].style.top = "0";
        //remove container
        outer_container.removeChild(inner_container);
        inner_container = undefined;
    };

    var createMenu = function() {
        var menu = document.createElement("div");
        menu.style.position = "fixed";
	    menu.style.right = "0";
	    menu.style.top = "0";
        menu.style.width = "100%";
        menu.style.height = "24px";
        menu.style.zIndex = "2147483647";
        menu.style.borderBottom = "1px solid lightgrey";
        menu.style.boxShadow = "0 0 10px black";
        menu.style.backgroundColor = "white";
        menu.style.paddingTop = "5px";
        menu.style.paddingLeft = "5px";
        menu.style.textAlign = "left";

        //add items
        //TODO
        var button = document.createElement("button");
        button.onclick = function() {
            marked_boxes.style.display = "none";
            var fireOnThis = document.getElementById('link_ff_extension_div');
            var event = document.createEvent("HTMLEvents");
            event.initEvent("my_event", true, true);
            fireOnThis.dispatchEvent(event);
        }
        button.innerHTML = "CLICK ME";
        button.style.marginLeft = "10px";
        menu.appendChild(button);

        //add closer
        var closer = document.createElement("div");
        closer.onclick = unload;
        closer.style.width = "13px";
        closer.style.height = "13px";
        closer.style.backgroundImage = "url('"+BASIC_URL+"sources/link_ff_extension_files/img/close.gif')";
        closer.style.position = "fixed";
        closer.style.top = "8px";
        closer.style.right = "8px";
        closer.style.cursor = "pointer";
        menu.appendChild(closer);

        return menu;
    };

    var createSelector = function() {
        selector_box = document.createElement("div");
        var top = document.createElement("div");
        var right = document.createElement("div");
        var bottom = document.createElement("div");
        var left = document.createElement("div");
        top.style.position = "absolute";
        right.style.position = "absolute";
        bottom.style.position = "absolute";
        left.style.position = "absolute";
        top.style.zIndex = "10000";
        right.style.zIndex = "10000";
        bottom.style.zIndex = "10000";
        left.style.zIndex = "10000";
        top.style.backgroundColor = "navy";
        right.style.backgroundColor = "navy";
        left.style.backgroundColor = "navy";
        bottom.style.backgroundColor = "navy";
        top.style.height = "3px";
        right.style.width = "3px";
        bottom.style.height = "3px";
        left.style.width = "3px";
        selector_box.style.display = "none";

        selector_box.appendChild(top);
        selector_box.appendChild(right);
        selector_box.appendChild(bottom);
        selector_box.appendChild(left);

        return selector_box;
    };

    var createMarked = function() {
        marked_boxes = document.createElement("div");
        marked_boxes.id = "link_ff_extension_selected";
        return marked_boxes;
    };


    var createExternalCotentBox = function() {
        var external_content_box = document.createElement("div");

        var url = encodeURIComponent(window.location);
        var iframe1 =  document.createElement("iframe");
        iframe1.src= BASIC_URL+"sources/link_ff_extension_files/html/link_ff_extension_main.html" + "?url="+url;
        iframe1.name = "link_ff_extension_iframe1";
        iframe1.style.zIndex = "10";
        iframe1.style.position ="fixed";
        iframe1.style.top = "40px";
        iframe1.style.right = "0";
        iframe1.style.width = "500px";
        iframe1.style.height = "400px";
        iframe1.style.border = "none";
        iframe1.style.background="none repeat scroll 0 0 transparent";

        external_content_box.appendChild(iframe1);
        external_content_box.style.position = "fixed";
        external_content_box.style.zIndex = "2147483646";
        external_content_box.style.top = "0";
        external_content_box.style.left = "0";
        external_content_box.style.display = "none";
        external_content_box.style.width = "100%";
        external_content_box.style.height = "100%";

        var shadow = document.createElement("div");
        shadow.style.backgroundColor = "black";
        shadow.style.opacity = "0.4";
        shadow.style.width = "100%";
        shadow.style.height = "100%";
        shadow.style.position = "absolute";

        external_content_box.appendChild(shadow);

        return external_content_box;
    }

    var functions =  {
        onmouseover : function(event) {
            if (inner_container != undefined) {
                //get coordinates
                var pos = getElementAbsolutePos(event.target);
                var top = pos.y;
                var left = pos.x;
                var width = parseInt(event.target.offsetWidth);
                var height = parseInt(event.target.offsetHeight);

                //set border
                var childs = selector_box.childNodes;
                childs[0].style.width = width + "px";
                childs[0].style.left = left + "px";
                childs[0].style.top = top + "px";
                childs[1].style.height = height + "px";
                childs[1].style.left = (left + width) + "px";
                childs[1].style.top = top + "px";
                childs[2].style.width = (3 + width) + "px";
                childs[2].style.left = left + "px";
                childs[2].style.top = (top + height) + "px";
                childs[3].style.height = height + "px";
                childs[3].style.left = left + "px";
                childs[3].style.top = top + "px";
                selector_box.style.display = "block";
            }
        },
        onmouseout : function(event) {
            if(inner_container != undefined) {
                selector_box.style.display = "none";
                event.stopPropagation();
            }
        },
        onclick : function(event) {
            if(inner_container != undefined) {
                //get coordinates
                var pos = getElementAbsolutePos(event.target);
                var top = pos.y;
                var left = pos.x;
                var width = parseInt(event.target.offsetWidth);
                var height = parseInt(event.target.offsetHeight);
                var deleteContainedBoxes = function(top, left, width, height) {
                    var boxes = marked_boxes.childNodes;
                    var rem = [];
                    for (var i = 0; i < boxes.length; i++) {
                        var box = boxes[i];
                        var boxtop = parseInt(box.style.top);
                        var boxleft = parseInt(box.style.left);
                        var boxwidth = parseInt(box.style.width);
                        var boxheight = parseInt(box.style.height);
                        if (boxleft >= left) {
                            if (boxtop >= top) {
                                if (left + width >= boxleft + boxwidth) {
                                    if (top + height >= boxtop + boxheight) {
                                        rem.push(box);
                                    }
                                }
                            }
                        }
                    }
                    //remove
                    for (var i = 0; i < rem.length; i++) {
                        rem[i].parentNode.removeChild(rem[i]);
                    }
                }
                deleteContainedBoxes(top,left,width,height);

                //marked box
                var marked = document.createElement("div");
                marked.style.position = "absolute";
                marked.style.top = top+"px";
                marked.style.left = left+"px";
                marked.style.width = width+"px";
                marked.style.height = height+"px";

                var content = document.createElement("div");
                content.style.display = "none";
                content.innerHTML = "<!--<div class='ff_extension_subpart'>"+encodeURI(new XMLSerializer().serializeToString(event.target))+"</div>-->";
                marked.appendChild(content);

                //closer
                var closer = document.createElement("div");
                closer.onclick = function(e) {
                    e.target.parentNode.parentNode.removeChild(e.target.parentNode);
                };
                closer.style.width = "13px";
                closer.style.height = "13px";
                closer.style.backgroundImage = "url('"+BASIC_URL+"sources/link_ff_extension_files/img/close.gif')";
                closer.style.position = "absolute";
                closer.style.top = "1px";
                closer.style.right = "1px";
                closer.style.cursor = "pointer";

                //colored background
                var filler = document.createElement("div");
                filler.style.backgroundColor = "navy";
                filler.style.opacity = "0.4";
                filler.style.width = "100%";
                filler.style.height = "100%";

                marked.appendChild(filler);
                marked.appendChild(closer);
                marked_boxes.appendChild(marked);

                event.preventDefault();
                event.stopPropagation();
            }
        }
    };

    var addMouseAction = function() {
        var addMouseAction = function(name) {
            var elements = document.body.getElementsByTagName(name);
            for (var i = 0; i < elements.length; i++) {
                elements[i].onmouseover = functions.onmouseover;
                elements[i].onmouseout = functions.onmouseout;
                elements[i].onclick = functions.onclick;
            }
        }
        IN_SELECTION.forEach(addMouseAction);
    };

    var load = function() {
        //do not load if already loaded
        if(inner_container != undefined) {
            unload();
            return;
        }
        inner_container = document.createElement("div");
        outer_container.appendChild(inner_container);

        //add menu and shift html
        inner_container.appendChild(createMenu());
        var html = document.getElementsByTagName("html")[0];
        html.style.position = "relative";
        html.style.top = "30px";

        inner_container.appendChild(createSelector());
        inner_container.appendChild(createMarked());
        inner_container.appendChild(createExternalCotentBox());
    };

    var init = function() {
        //append mouseover and mouseout listeners
        addMouseAction();
        //append hidden button and start
        var button = document.createElement("button");
        button.id="link_ff_extension_button";
        button.onclick = load;
        button.style.display = "none";
        outer_container = document.getElementById("link_ff_extension_div");
        outer_container.appendChild(button);

        button.click();
    };

    init();

})();